import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable, Subject} from 'rxjs';
import {AuthService} from "../../services/auth.service";
import {ConfigService} from "../../services/config.service";
import {Sell} from "../../model/product/entity/sell";
import {map} from "rxjs/operators";
import {PrintService} from "../print.service";
import * as moment from "moment";

@Injectable({
  providedIn: 'root'
})
export class SellService {

    private baseUrl = this.configService.api.url + '/sells';  // URL to web API
    private subject: any = {
        create: new Subject<any>(),
        delete: new Subject<any>(),
        update: new Subject<any>(),
        refresh: new Subject<any>()
    };

    constructor(private http: HttpClient, private authService: AuthService, private configService: ConfigService, private printService: PrintService) {
    }

    on(event, callback) {
        return this.subject[event].subscribe(value => callback(value));
    }

    emit(event, value: any) {
        return this.subject[event].next(value);
    }

    create(sell: Sell): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        sell.create();
        return this.http.post(this.baseUrl + '/create', {sell: sell.toJSON()}, options);
    }

    createMany(sells: Sell[]): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        sells.forEach(sell => {
            sell.create();
        });
        return this.http.post(this.baseUrl + '/create/many', {sells: sells.map(item => item.toJSON())}, options);
    }

    delete(id: string): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.post(this.baseUrl + '/' + id + '/remove', options);
    }

    update(sell: Sell): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.post(this.baseUrl + '/' + sell._id + '/update', {sell: sell.toJSON()}, options);
    }

    updateMany(sells: Sell[]): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.post(this.baseUrl + '/update/many', {sells: sells.map(item => item.toJSON())}, options);
    }

    getAll(): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/', options).pipe(map( (res:any) => {
            return res.map(item => {
                const sell = new Sell();
                sell.fromJSON(item);
                return sell;
            });
        }));
    }

    getOne(id: string): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/detail/' + id, options).pipe(map(item => {
            const sell = new Sell();
            sell.fromJSON(item);
            return sell;
        }));
    }

    getByDate(start, end): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/date/' + start + '/' + end, options).pipe(map( (res:any) => {
            return res.map(item => {
                const sell = new Sell();
                sell.fromJSON(item);
                return sell;
            });
        }));
    }

    print(sells: Sell[]) {
        if (!sells || !sells.length) return;
        const total = sells.reduce((acc, cur) => {
            return acc + cur.price * cur.amount;
        },0);
        const customer = sells[0].customer;
        let html = `<div style="padding: 10px; height: 100%; display: grid; grid-template-rows: auto 1fr auto; grid-gap: 10px;">
                        <div style="padding: 50px 26px 10px 26px; display: grid; grid-template-rows: auto auto; grid-gap: 10px;">
                            <span style="font-size: 32px; justify-self: center">配件清单</span>
                            <div style="display: grid; grid-template-columns: 1fr auto">
                                <span style="font-size: 16px">客户名称: ${customer.name}(${customer.phone})</span>
                                <span style="font-size: 16px">打印日期: ${moment().format("YYYY-MM-DD")}</span>
                            </div>
                        </div>
                        <div style="height: 100%; padding: 10px 26px; display: grid; grid-auto-flow: row; grid-auto-rows: min-content; grid-gap: 10px;">`;

        sells.forEach((sell, index) => {
            html += `<div style="padding: 10px 0px; height: 120px; display: grid; justify-content: center; grid-gap: 10px; grid-template-columns: 36px 1fr 150px 80px 56px 100px; border-bottom: 1px solid #333;">
                            <span style="font-size: 12px;">${index + 1}</span>
                            <div style="display: grid; grid-gap: 3px; grid-template-rows: auto auto auto; ">
                                <span style="font-size: 16px; font-weight: bold;">${sell.product.name}</span>
                                <span style="font-size: 12px;">编码 ${sell.product.code}</span>
                                <span style="font-size: 12px;">订单编号 ${sell.code}</span>
                            </div>
                            <span style="font-size: 14px;"> ${moment(sell.date).format("YYYY-MM-DD HH:mm:ss")} </span>
                            <span style="font-size: 16px;"> 单价:${sell.price} </span>
                            <span style="font-size: 16px;"> 数量:${sell.amount} </span>
                            <span style="font-size: 16px;"> 小计:${sell.price * sell.amount} </span>
                     </div>`
        });
        html += `<div style="display: grid; padding: 10px 20px; justify-items: end; grid-auto-flow: column; grid-gap: 10px;">
                    <span style="font-size: 28px;"> 总计: ${total} </span>
                 </div>`;
        html += `</div>`;
        this.printService.printHtml(html);
    }

}
